﻿using AutoMapper;
using AutoMapper.QueryableExtensions;
using GGetTestService.Dto.Student;
using GGetTestService.Entity;
using GGetTestService.Extension;
using GGetTestService.Repository;
using GGetTestService.Repository.UnitOfWork;
using GGetTestService.Services.Base;
using GGetTestService.Services.Interface;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GGetTestService.Services
{
    public class StudentService : BaseService<Student>, IStudentService
    {
        private readonly IUnitOfWork _unitOfWork;
        private readonly IMapper _mapper;
        private IRepository<Student> _studentRepository;

        public StudentService(IUnitOfWork unitOfWork, IMapper mapper) : base(unitOfWork)
        {
            _unitOfWork = unitOfWork;
            _mapper = mapper;
            _studentRepository = _unitOfWork.GetRepository<Student>();
        }

        public async Task AddStudentAsync(Student student)
        {
            await _studentRepository.AddAsync(student);
            await _unitOfWork.SaveChangesAsync();
        }

        public async Task<object> GetStudentInnerJoinTeacher()
        {
            var studentQueryable = _studentRepository.Queryable;
            var teacherQueryable = _unitOfWork.GetRepository<Teacher>().Queryable;

            var result = await studentQueryable
                              .Join(teacherQueryable, x => x.TeacherId, y => y.Id, (s, t) => new { Student = s, Teacher = t })
                              .ToListAsync();
            return await _studentRepository.Queryable.Include(x => x.Teacher).ToListAsync();
        }

        public async Task<IEnumerable<Student>> GetStudentListAsync()
        {
            var studentRepository = _unitOfWork.GetRepository<Student>();
            var stuQueryable = studentRepository.Queryable;

            var str = stuQueryable.ToQueryString();

            var list123 = await stuQueryable.Where(x => x.Age > 0 && x.Teacher.Age > 10)
                                            .Include(x => x.Teacher)
                                            .OrderBy(p => p.Age).ThenBy(p => p.Teacher.Age)
                                            .ProjectTo<StudentDto>(_mapper)
                                            .ToListAsync();

            var list = await stuQueryable.Where(x => x.Age > 0 && x.Teacher.Age > 10)
                                         .Include(x => x.Teacher)
                                         .OrderBy(p => p.Age).ThenBy(p => p.Teacher.Age)
                                         .ToListAsync();

            #region MyRegion

            //var name = "李白";
            //var age = 17;
            //Expression<Func<Student, bool>> expression = x => true;
            //expression = expression.And(age != 0, x => x.Age == age);

            //#region 直接查找Dto类型

            //{
            //    var a = await stuQueryable.Where(expression).ProjectTo<StudentDto>(_mapper).ToListAsync();
            //    var b = stuQueryable.ProjectTo<StudentDto>(_mapper).ToList();
            //}

            //#endregion 直接查找Dto类型

            //#region 测试And

            //{
            //    var a = await stuQueryable.And(!name.IsNullOrEmpty(), x => x.Name == name)
            //                              .And(age != 0, x => x.Age == age)
            //                              .ToListAsync();
            //}

            //#endregion 测试And

            //#region 测试排序

            //{
            //    var a = await stuQueryable.OrderByBatch("Age,Name").ToListAsync();

            //    var b = await stuQueryable.OrderByBatch("-Age,Name").ToListAsync();
            //}

            //#endregion 测试排序

            #endregion MyRegion

            return list;
        }
    }
}